package main

import (
	"flag"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
	"log"
	"os"
	"strconv"
	"xin/raft"
)

func main() {
	id := flag.Uint64("id", 1, "id")
	cluster := flag.String("cluster", "1@127.0.0.1:3000,2@127.0.0.1:3001,3@127.0.0.1:3002", "cluster address")
	port := flag.Int("port", 3000, "port number")

	flag.Parse()

	logger := newLogger(*id)

	// 初始化元数据存储器
	matePath := "./node_" + strconv.FormatUint(*id, 10)
	storage := raft.NewLocalRaftMetaStorage(matePath, logger)

	// 初始化通信器
	transport := raft.NewTcpTransport(*port, logger)

	//transport := raft.NewMemoryTransport(logger)

	// 初始化配置
	config := raft.NewDefaultConfig(*cluster, *port)

	w := raft.NewLog(raft.NewLogEmptyStore(), logger) // 测试选举使用 election 分支

	// 初始化 raft
	r, err := raft.NewRaft(*id, storage, transport, w, config, logger)
	if err != nil {
		log.Panic(err)
	}

	// Init
	err = r.Init()
	if err != nil {
		log.Panic(err)
	}

	// 启动
	r.Start()
}

func newLogger(id uint64) *zap.Logger {
	encoderConfig := zap.NewDevelopmentEncoderConfig()
	encoderConfig.TimeKey = "time"
	encoderConfig.EncodeTime = zapcore.TimeEncoderOfLayout("2006-01-02 15:04:05")

	encoder := zapcore.NewConsoleEncoder(encoderConfig)
	logFileName := "./node_" + strconv.FormatUint(id, 10) + ".log"
	logFile, _ := os.Create(logFileName)
	writeSync := zapcore.NewMultiWriteSyncer(zapcore.AddSync(os.Stdout), zapcore.AddSync(logFile))
	core := zapcore.NewCore(encoder, writeSync, zapcore.DebugLevel)
	logger := zap.New(core, zap.AddCaller())
	return logger
}
